#ifdef WIN32
#ifndef __cplusplus
#error Please compile with a C++ compiler.
#endif
#endif

#if defined(USE_WINDOWS_GDIPLUS)
#include <Windows.h>
#include <GdiPlus.h>

#pragma comment(lib, "gdiplus.lib")
#else
#include <GdiPlusFlat.h>
#endif

#if defined(USE_WINDOWS_GDIPLUS)
using namespace Gdiplus;
using namespace DllExports;
#endif

#include <assert.h>
#if !defined(USE_WINDOWS_GDIPLUS)
#include <tiffio.h>
#endif
#include "testhelpers.h"

static const char *file = "temp_asset.tif";
static WCHAR wFile[] = {'t', 'e', 'm', 'p', '_', 'a', 's', 's', 'e', 't', '.', 't', 'i', 'f', 0};
GpImage *image;

#define createFile(buffer, expectedStatus) \
{ \
	GpStatus status; \
	FILE *f = fopen (file, "wb+"); \
	assert (f); \
	fwrite ((void *) buffer, sizeof (BYTE), sizeof (buffer), f); \
	fclose (f); \
 \
	status = GdipLoadImageFromFile (wFile, &image); \
	assertEqualInt (status, expectedStatus); \
}

#define createFileSuccess(buffer, width, height, flags, propertyCount) \
{ \
	createFile (buffer, Ok); \
	verifyBitmap (image, tifRawFormat, PixelFormat24bppRGB, width, height, flags, propertyCount, TRUE); \
	GdipDisposeImage (image); \
}

static void test_valid ()
{
	BYTE validData24bpp[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
	BYTE missingRequiredTagsAccordingToSpec[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x05, 0x00,

		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
	};
	BYTE invalidNextIFDOffset[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0xFF, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};

	createFileSuccess (validData24bpp, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealDPI | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 15);

	// Version not 0x2A.
	validData24bpp[3] = 0x00;
	createFileSuccess (validData24bpp, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealDPI | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 15);

	createFileSuccess (missingRequiredTagsAccordingToSpec, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 5);
	createFileSuccess (invalidNextIFDOffset, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealDPI | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 15);
}

static void test_units ()
{
	BYTE invalidXResolutionOffset[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
	BYTE invalidYResolutionOffset[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
	BYTE zeroXResolution[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
	BYTE zeroYResolution[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	BYTE noXResolution[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xBC, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC2, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* YResolution Data */           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	BYTE noYResolution[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0E, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xBC, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC2, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};

	createFileSuccess (invalidXResolutionOffset, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 14);
	createFileSuccess (invalidYResolutionOffset, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 14);
	createFileSuccess (zeroXResolution, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 15);
	createFileSuccess (zeroYResolution, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 15);
	createFileSuccess (noXResolution, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 13);
	createFileSuccess (noYResolution, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 13);
}

static void test_validGdiplus ()
{
	BYTE missingBitsPerSampleTag[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0E, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCA, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
	BYTE missingSamplesPerPixelTag[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0E, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xBC, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCA, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
	BYTE invalidBitsPerSampleR[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x07, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
	BYTE invalidBitsPerSampleG[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x07, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
	BYTE invalidBitsPerSampleB[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x07, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};

	// There isn't much we can do about these differences as we let libtiff handle tiff decoding.
#if defined(USE_WINDOWS_GDIPLUS)
	createFileSuccess (missingBitsPerSampleTag, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealDPI | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 14);
	createFileSuccess (missingSamplesPerPixelTag, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealDPI | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 14);

	createFileSuccess (invalidBitsPerSampleR, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealDPI | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 15);
	createFileSuccess (invalidBitsPerSampleG, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealDPI | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 15);
	createFileSuccess (invalidBitsPerSampleB, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealDPI | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 15);
#else
	createFile (missingBitsPerSampleTag, OutOfMemory);
	createFile (missingSamplesPerPixelTag, OutOfMemory);

	createFile (invalidBitsPerSampleR, OutOfMemory);
	createFile (invalidBitsPerSampleG, OutOfMemory);
	createFile (invalidBitsPerSampleB, OutOfMemory);
#endif
}

static void test_invalidHeader ()
{
	BYTE noVersionNumberLE[]    = {0x49, 0x49};
	BYTE noVersionNumberBE[]    = {0x4D, 0x4D};
	BYTE shortVersionNumberLE[] = {0x49, 0x49, 0x2A};
	BYTE shortVersionNumberBE[] = {0x4D, 0x4D, 0x2A};
	BYTE noOffsetLE[]           = {0x49, 0x49, 0x2A, 0x00};
	BYTE noOffsetBE[]           = {0x4D, 0x4D, 0x00, 0x2A};
	BYTE shortOffsetLE[]        = {0x49, 0x49, 0x2A, 0x00, 0x08};
	BYTE shortOffsetBE[]        = {0x4D, 0x4D, 0x00, 0x2A, 0x00};
	BYTE zeroOffsetLE[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
	BYTE overlappingOffsetLE[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x07, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
	BYTE invalidOffsetLE[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};

	createFile (noVersionNumberLE, OutOfMemory);
	createFile (noVersionNumberBE, OutOfMemory);
	createFile (shortVersionNumberLE, OutOfMemory);
	createFile (shortVersionNumberBE, OutOfMemory);
	createFile (noOffsetLE, OutOfMemory);
	createFile (noOffsetBE, OutOfMemory);
	createFile (shortOffsetLE, OutOfMemory);
	createFile (shortOffsetBE, OutOfMemory);
	createFile (zeroOffsetLE, OutOfMemory);
	createFile (overlappingOffsetLE, OutOfMemory);
	createFile (invalidOffsetLE, OutOfMemory);
}

static void test_invalidFileDirectory ()
{
	BYTE noNumberOfEntriesLE[] = {
		/* Header */ 0x49, 0x49, 0x2A, 0x00, 0x80, 0x00, 0x00, 0x00
	};
	BYTE noNumberOfEntriesBE[] = {
		/* Header */ 0x4D, 0x4D, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08
	};
	BYTE shortNumberOfEntriesLE[] = {
		/* Header */ 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* IFD 1 */  0x01
	};
	BYTE shortNumberOfEntriesBE[] = {
		/* Header */ 0x4D, 0x4D, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08,
		/* IFD 1 */  0x00
	};
	BYTE noNextIFDOffsetLE[] = {
		/* Header */          0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* IFD 1 */           0x01, 0x00,
		/* NewSubFileType */  0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	BYTE noNextIFDOffsetBE[] = {
		/* Header */          0x4D, 0x4D, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08,
		/* IFD 1 */           0x00, 0x01,
		/* NewSubFileType */  0x00, 0xFE, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
	};
	BYTE shortNextIFDOffsetLE[] = {
		/* Header */          0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* IFD 1 */           0x01, 0x00,
		/* NewSubFileType */  0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* IFD 1 */           0x00, 0x00, 0x00
	};
	BYTE shortNextIFDOffsetBE[] = {
		/* Header */          0x4D, 0x4D, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08,
		/* IFD 1 */           0x00, 0x01,
		/* NewSubFileType */  0x00, 0xFE, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
		/* IFD 1 */           0x00, 0x00, 0x00
	};
	BYTE zeroNumberOfEntries[] = {
		/* Header */          0x4D, 0x4D, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08,
		/* IFD 1 */           0x00, 0x00,
		/* IFD 1 */           0x00, 0x00, 0x00, 0x00
	};
#if TIFFLIB_VERSION >= 20150621
	BYTE recursiveNextIFDOffset[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x0E, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
#endif

	createFile (noNumberOfEntriesLE, OutOfMemory);
	createFile (noNumberOfEntriesBE, OutOfMemory);
	createFile (shortNumberOfEntriesLE, OutOfMemory);
	createFile (shortNumberOfEntriesBE, OutOfMemory);
	createFile (noNextIFDOffsetLE, OutOfMemory);
	createFile (noNextIFDOffsetBE, OutOfMemory);
	createFile (shortNextIFDOffsetLE, OutOfMemory);
	createFile (shortNextIFDOffsetBE, OutOfMemory);
	createFile (zeroNumberOfEntries, OutOfMemory);
	// Libtiff 4.0.4, released on June 21st 2015, fixed this bug. However, outdated platforms may not have this fix.
#if TIFFLIB_VERSION >= 20150621
	createFile (recursiveNextIFDOffset, OutOfMemory);
#endif
}

static void test_invalidTag ()
{
	BYTE noTagIdLE[] = {
		/* Header */ 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* IFD 1 */  0x01, 0x00
	};
	BYTE noTagIdBE[] = {
		/* Header */ 0x4D, 0x4D, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08,
		/* IFD 1 */  0x00, 0x01
	};
	BYTE shortTagIdLE[] = {
		/* Header */          0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* IFD 1 */           0x01, 0x00,
		/* NewSubFileType */  0xFE
	};
	BYTE shortTagIdBE[] = {
		/* Header */          0x4D, 0x4D, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08,
		/* IFD 1 */           0x00, 0x01,
		/* NewSubFileType */  0x00
	};
	BYTE noTagDataTypeLE[] = {
		/* Header */          0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* IFD 1 */           0x01, 0x00,
		/* NewSubFileType */  0xFE, 0x00
	};
	BYTE noTagDataTypeBE[] = {
		/* Header */          0x4D, 0x4D, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08,
		/* IFD 1 */           0x00, 0x01,
		/* NewSubFileType */  0x00, 0xFE
	};
	BYTE shortTagDataTypeLE[] = {
		/* Header */          0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* IFD 1 */           0x01, 0x00,
		/* NewSubFileType */  0xFE, 0x00, 0x04
	};
	BYTE shortTagDataTypeBE[] = {
		/* Header */          0x4D, 0x4D, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08,
		/* IFD 1 */           0x00, 0x01,
		/* NewSubFileType */  0x00, 0xFE, 0x00
	};
	BYTE noTagDataCountLE[] = {
		/* Header */          0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* IFD 1 */           0x01, 0x00,
		/* NewSubFileType */  0xFE, 0x00, 0x04, 0x00
	};
	BYTE noTagDataCountBE[] = {
		/* Header */          0x4D, 0x4D, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08,
		/* IFD 1 */           0x00, 0x01,
		/* NewSubFileType */  0x00, 0xFE, 0x00, 0x04
	};
	BYTE shortTagDataCountLE[] = {
		/* Header */          0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* IFD 1 */           0x01, 0x00,
		/* NewSubFileType */  0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00
	};
	BYTE shortTagDataCountBE[] = {
		/* Header */          0x4D, 0x4D, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08,
		/* IFD 1 */           0x00, 0x01,
		/* NewSubFileType */  0x00, 0xFE, 0x00, 0x04, 0x00, 0x00, 0x00
	};
	BYTE noTagDataOffsetLE[] = {
		/* Header */          0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* IFD 1 */           0x01, 0x00,
		/* NewSubFileType */  0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00
	};
	BYTE noTagDataOffsetBE[] = {
		/* Header */          0x4D, 0x4D, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08,
		/* IFD 1 */           0x00, 0x01,
		/* NewSubFileType */  0x00, 0xFE, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01
	};
	BYTE shortTagDataOffsetLE[] = {
		/* Header */          0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* IFD 1 */           0x01, 0x00,
		/* NewSubFileType */  0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	BYTE shortTagDataOffsetBE[] = {
		/* Header */          0x4D, 0x4D, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08,
		/* IFD 1 */           0x00, 0x01,
		/* NewSubFileType */  0x00, 0xFE, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
	};
	BYTE invalidDataOffsetLE[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};

	createFile (noTagIdLE, OutOfMemory);
	createFile (noTagIdBE, OutOfMemory);
	createFile (shortTagIdLE, OutOfMemory);
	createFile (shortTagIdBE, OutOfMemory);
	createFile (noTagDataTypeLE, OutOfMemory);
	createFile (noTagDataTypeBE, OutOfMemory);
	createFile (shortTagDataTypeLE, OutOfMemory);
	createFile (shortTagDataTypeBE, OutOfMemory);
	createFile (noTagDataCountLE, OutOfMemory);
	createFile (noTagDataCountBE, OutOfMemory);
	createFile (shortTagDataCountLE, OutOfMemory);
	createFile (shortTagDataCountBE, OutOfMemory);
	createFile (noTagDataOffsetLE, OutOfMemory);
	createFile (noTagDataOffsetBE, OutOfMemory);
	createFile (shortTagDataOffsetLE, OutOfMemory);
	createFile (shortTagDataOffsetBE, OutOfMemory);
	createFile (invalidDataOffsetLE, OutOfMemory);
}

static void test_missingTag ()
{
	BYTE missingImageWidthTag[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0E, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xBC, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCA, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
	BYTE missingImageHeightTag[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0E, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xBC, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCA, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
	BYTE missingStripOffsetsTag[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0E, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xBC, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCA, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};

	createFile (missingImageWidthTag, OutOfMemory);
	createFile (missingImageHeightTag, OutOfMemory);
	createFile (missingStripOffsetsTag, OutOfMemory);
}

static void test_invalidSpecificTag ()
{
	BYTE zeroImageWidth[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
	BYTE zeroImageHeight[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
	BYTE largeImageWidth[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
	BYTE largeImageHeight[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};
	BYTE largeImageWidthAndHeight[] = {
		/* Header */                     0x49, 0x49, 0x2A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x80, 0x3F, 0xE0, 0x50, 0x10, 0x00,
		/* Number of Tags */             0x0F, 0x00,

		/* NewSubFileType */             0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		/* ImageWidth */                 0x00, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
		/* ImageHeight */                0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
		/* BitsPerSample */              0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
		/* Compression */                0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* PhotometricInterpretation */  0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* StripOffsets */               0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
		/* SamplesPerPixel */            0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
		/* RowsPerStrip */               0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* StripByteCounts */            0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
		/* XResolution */                0x1A, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00,
		/* YResolution */                0x1B, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00,
		/* PlanarConfiguration */        0x1C, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		/* ResolutionUnit */             0x28, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Predictor */                  0x3D, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		/* Next IFD Offset */            0x00, 0x00, 0x00, 0x00,

		/* BitsPerSample Data */         0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
		/* XResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00,
		/* YResolution Data */           0x00, 0x77, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x00
	};

	createFile (zeroImageWidth, OutOfMemory);
	createFile (zeroImageHeight, OutOfMemory);
	createFile (largeImageWidth, OutOfMemory);
	createFile (largeImageHeight, OutOfMemory);
	createFile (largeImageWidthAndHeight, OutOfMemory);
}

int
main (int argc, char**argv)
{
	STARTUP;

	test_valid ();
	test_units ();
	test_validGdiplus ();
	test_invalidHeader ();
	test_invalidFileDirectory ();
	test_invalidTag ();
	test_missingTag ();
	test_invalidSpecificTag ();

	deleteFile (file);

	SHUTDOWN;
	return 0;
}
